#include <uart_app.h>

#include <rtthread.h>
#include <rtdevice.h>
#include <string.h>
#include <ipc/ringbuffer.h>  // 包含 RT-Thread 的 ringbuffer 头文件
#include <stdio.h>           // 标准输入输出

#define BUFFER_SIZE 216                // 环形缓冲区大小
#define UART_DEVICE_NAME "uart1"       // 串口设备名称
#define DEBUG_MESSAGE "Uart Application Initialized.\r\n"
#define UART_TIMEOUT_TICKS 50          // 超时的系统tick数，具体值根据需求调整

/* 环形缓冲区存储池 */
static uint8_t rb_pool[BUFFER_SIZE];

/* 环形缓冲区对象 */
static struct rt_ringbuffer uart_rb;

/* 读取数据的缓冲区 */
static uint8_t uart_read_buffer[BUFFER_SIZE];

/* 用于同步的信号量 */
static struct rt_semaphore rx_sem;

/* UART设备指针（用于重定向） */
static rt_device_t uart_dev_redirect = RT_NULL;

struct rt_device *uart_dev;

/* 记录上一次接收数据的tick */
static rt_tick_t last_rx_tick = 0;

int u1_printf(const char *format, ...)
{
    char buffer[512];  // 缓冲区大小，根据需求调整
    va_list args;
    va_start(args, format);

 // 使用 vsnprintf 格式化字符串到 buffer 中
    vsnprintf(buffer, sizeof(buffer), format, args);

    va_end(args);

 // 通过 rt_device_write 发送格式化后的字符串到串口1
    rt_device_write(uart_dev_redirect, 0, buffer, strlen(buffer));

    return strlen(buffer);
}

/* UART接收回调函数 */
static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size)
{
    rt_size_t read_size;
    rt_uint8_t temp_buffer[BUFFER_SIZE];

 /* 复位计时变量 */
    last_rx_tick = rt_tick_get();

 /* 从串口设备读取数据 */
    read_size = rt_device_read(uart_dev, 0, temp_buffer, BUFFER_SIZE);

    if (read_size > 0)
    {
        /* 将读取的数据写入应用环形缓冲区 */
        size = rt_ringbuffer_put(&uart_rb, temp_buffer, read_size);
        if (size < read_size)
        {
            /* 如果环形缓冲区空间不足，丢弃多余的数据 */
            u1_printf("Ringbuffer full! Data lost.\n");
        }
    }
    return RT_EOK;
 }

/* 数据处理线程入口函数 */
static void uart_thread_entry(void *parameter)
{
    rt_size_t size;
    rt_tick_t current_tick;

    while (1)
    {
        /* 获取当前的tick值 */
        current_tick = rt_tick_get();

        /* 判断是否已经超时 */
        if (current_tick - last_rx_tick >= UART_TIMEOUT_TICKS)
        {
            /* 如果超时了，认为数据已经接收完成，可以处理数据 */
            if (rt_ringbuffer_data_len(&uart_rb) > 0)
            {
                size = rt_ringbuffer_get(&uart_rb, uart_read_buffer, sizeof(uart_read_buffer) - 1);
                if (size > 0)
                {
                    /* 发送调试信息 */
                    u1_printf("ringbuffer data: %s\r\n", uart_read_buffer);

                    /* 清空读取缓冲区 */
                    memset(uart_read_buffer, 0, sizeof(uart_read_buffer));
                }
            }
        }
        rt_thread_delay(50);
    }
}

/* UART应用初始化函数 */
int uart_init(void)
{
    rt_err_t result;
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
    rt_thread_t thread;

    /* 初始化信号量 */
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);

    /* 初始化环形缓冲区 */
    rt_ringbuffer_init(&uart_rb, rb_pool, sizeof(rb_pool));

    /* 查找串口设备 */
    uart_dev = rt_device_find(UART_DEVICE_NAME);
    if (!uart_dev)
    {
        u1_printf("Find %s failed!\n", UART_DEVICE_NAME);
        return RT_ERROR;
    }

 /* 配置串口参数（可根据需要修改） */
    config.baud_rate = BAUD_RATE_115200; /* 波特率 */
    config.data_bits = DATA_BITS_8;      /* 数据位 */
    config.stop_bits = STOP_BITS_1;      /* 停止位 */
    config.parity    = PARITY_NONE;      /* 无奇偶校验 */
    config.bufsz     = BUFFER_SIZE;      /* 缓冲区大小 */

    /* 控制串口设备，设置配置参数 */
    result = rt_device_control(uart_dev, RT_DEVICE_CTRL_CONFIG, &config);
    if (result != RT_EOK)
    {
        u1_printf("Configure %s failed!\n", UART_DEVICE_NAME);
        return RT_ERROR;
    }

    /* 打开串口设备，以中断接收模式打开 */
    result = rt_device_open(uart_dev, RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_INT_TX);
    if (result != RT_EOK)
    {
        u1_printf("Open %s failed!\n", UART_DEVICE_NAME);
        return RT_ERROR;
    }

    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(uart_dev, uart_rx_ind);

    /* 重定向输出到UART */
    uart_dev_redirect = uart_dev;

    /* 发送初始化消息 */
    u1_printf("%s", DEBUG_MESSAGE);

    /* 创建数据处理线程 */
    thread = rt_thread_create("uart_thread",
                               uart_thread_entry,
                               (void *)uart_dev,
                               4096,//1024会溢出
                               RT_THREAD_PRIORITY_MAX / 2,
                               10);
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        u1_printf("Create uart_thread failed!\n");
        return RT_ERROR;
    }

    return RT_EOK;
}
